from django.shortcuts import render,redirect,HttpResponse
from app.models import User,Press,Book,Booktype
import os
from django.urls import reverse

# Create your views here.

# 物理删除  逻辑删除


# 跳转页面
def login(request):

    # 判断请求方法
    if request.method == "GET":
        return render(request,"login.html")
    else:
        # 接收登录界面的用户名和密码
        username = request.POST.get("username")
        password = request.POST.get("password")

        # select * from app_user where username = ? and password = ?
        if User.objects.filter(username=username, password=password):

            # 保存登录信息
            response = redirect("/presslist")
            # 通过响应设置登录cookie
            # response.set_cookie("login","1")

            # 通过session来保存登录信息
            request.session["login"] = "1"

            return response
        else:
            return render(request, "login.html", {"msg": "用户名或密码错误"})

# 登录装饰器
from django.contrib import messages
def login_decorator(view_fun):
    def inner(request,*args, **kwargs):

        # 判断session是否有登录信息
        if request.session.get("login"):
            return view_fun(request,*args, **kwargs)  # 方法正常执行
        messages.warning(request,"登录信息已过期，请重新登录！")
        return redirect("/login/")
    return inner





# 装饰器
import time
def codeTime(fn):
    def inner(*args, **kwargs):
        begin = time.time()
        res = fn(*args, **kwargs)
        end = time.time()
        print("代码运行时长%.2f" % (end - begin))
        return res
    return inner

# 出版社列表  get
@login_decorator
def presslist(request):

    # 先判断是否正常登录
    # if request.COOKIES.get("login") == "1":
    # if request.session.get("login") == "1":
    # 调用orm查询所有的出版社信息  select * from app_press;
    presslist = Press.objects.all()
    # 跳转至出版社列表页面
    return render(request, "presslist.html", {"presslist": presslist})

    # 说明请求cookie有问题  重定向到登录页面
    # return redirect("/login/")




# 出版社搜索  presssearch
@login_decorator
def presssearch(request):

    pressname = request.POST.get("pressname")

    presslist = Press.objects.filter(pressname__icontains=pressname)
    # 跳转至出版社列表页面
    return render(request,"presslist.html",{"presslist":presslist,"pressname":pressname})








# 出版社添加  get
# @codeTime
@login_decorator
def pressadd(request):
    # 判断请求方法
    if request.method == "GET":
        return render(request, "pressadd.html")
    else:
        # 页面中用户点击添加按钮的时候 接收出版社名称、出版社地址
        pressname = request.POST.get("pressname")
        pressaddress = request.POST.get("pressaddress")

        # 调用ORM中的添加api方法
        Press.objects.create(pressname=pressname,pressaddress=pressaddress)

        # 跳转页面 出版社列表
        return redirect("/presslist")


"""
    类视图  提供可以用来跳转页面的类
"""
from django.views import View
from django.utils.decorators import method_decorator

class PressAdd(View):

    @method_decorator(codeTime)
    def dispatch(self, request, *args, **kwargs):
        print("方法调用之前")
        res = super().dispatch(request, *args, **kwargs)
        print("方法调用之后")
        return res

    #@method_decorator(codeTime)
    def get(self,request):
        print("get请求")
        return render(request, "pressadd.html")

    #@method_decorator(codeTime)
    def post(self,request):
        print("post请求")
        # 页面中用户点击添加按钮的时候 接收出版社名称、出版社地址
        pressname = request.POST.get("pressname")
        pressaddress = request.POST.get("pressaddress")

        # 调用ORM中的添加api方法
        Press.objects.create(pressname=pressname, pressaddress=pressaddress)

        # 跳转页面 出版社列表
        return redirect("/presslist")



# 出版社删除  delete
@login_decorator
def pressdelete(request,delete_id):

    print(delete_id)

    # 接收前台页面要删除的id编号
    #delete_id = request.GET.get("id")
    # 调用orm删除 根据id 出版社信息
    Press.objects.filter(id=delete_id).delete()

    # 跳转页面 出版社列表
    # return redirect("/presslist/")
    return redirect(reverse('presslist'))

# 出版社修改  update
def pressupdate(request):

    if request.method == "POST":
        # 从修改页面接收所有数据，包含隐藏域中的id值
        id = request.POST.get("id")
        pressname = request.POST.get("pressname")
        pressaddress = request.POST.get("pressaddress")

        # 调用orm 执行修改方法  持久化对象
        update_press = Press.objects.get(id=id)


        # 通过 持久化对象 设置要修改的属性
        update_press.pressname = pressname
        update_press.pressaddress = pressaddress

        # 通过 orm 调用save方法，将持久化对象重新保存（更新）
        update_press.save()   # update ....

        # 跳转页面 出版社列表
        return redirect("/presslist")


    # 接收前台页面要删除的id编号
    update_id = request.GET.get("id")
    # 调用orm 查询id对应的出版社对象信息   select * from app_press where id = ?
    press = Press.objects.get(id=update_id)
    # 跳转页面 出版社列表
    return render(request,"pressupdate.html",{"press":press})

# 图书列表  get
@login_decorator
def booklist(request):
    # 调用orm查询所有的出版社信息  select * from app_book;
    booklist = Book.objects.all()


    # select * from app_press ap,app_book ab where ap.press_id = ab.id

    # 跳转至出版社列表页面
    return render(request,"booklist.html",{"booklist":booklist})

# 图书增加  bookadd
@login_decorator
def bookadd(request):
    # 请求方式
    if request.method == "POST":
        bookname = request.POST.get("bookname")
        bookauthor = request.POST.get("bookauthor")
        bookprice = request.POST.get("bookprice")
        press_id = request.POST.get("press_id")


        #接收图片对象
        bookimg_obj = request.FILES.get("bookimg")

        # 图书图片名称  字符串类型
        bookimg_name = bookimg_obj.name

        # 拼接图片存储的位置
        bookimg_path = "static/img"

        # 拼接需要向数据库存储的图书图片路径信息
        bookimg = os.path.join(bookimg_path,bookimg_name)

        # 将图片真正的存储至服务器指定位置
        with open(bookimg,"wb") as file:
            # 将文件一点点读取并写入
            for chunk in bookimg_obj.chunks():
                file.write(chunk)

        bookimg = "/"+bookimg
        # 调用orm的create 执行添加操作
        Book.objects.create(bookname=bookname,bookauthor=bookauthor,bookprice=bookprice,bookimg=bookimg,press_id=press_id)
        # 重定向到图书列表页面
        return redirect("/booklist")


    # 查询一下出版社列表
    presslist = Press.objects.all()
    return render(request, "bookadd.html",{"presslist":presslist})

# 图书删除  delete
@login_decorator
def bookdelete(request):
    # 接收前台页面要删除的id编号
    delete_id = request.GET.get("id")
    # 调用orm删除 根据id 出版社信息
    Book.objects.filter(id=delete_id).delete()
    # 跳转页面 出版社列表
    return redirect("/booklist")
@login_decorator
def bookupdate(request):

    if request.method == "POST":
        # 从修改页面接收所有数据，包含隐藏域中的id值
        id = request.POST.get("id")
        bookname = request.POST.get("bookname")
        bookauthor = request.POST.get("bookauthor")
        bookprice = request.POST.get("bookprice")
        press_id = request.POST.get("press_id")

        # 调用 orm 执行修改方法  持久化对象
        update_book = Book.objects.get(id=id)

        # 接收用户修改的图片
        bookimg_obj = request.FILES.get("bookimg")

        # 判断用户是否上传新文件   判断bookimg_obj是否有内容
        if bookimg_obj:
            # 图书图片名称  字符串类型
            bookimg_name = bookimg_obj.name

            # 拼接图片存储的位置
            bookimg_path = "static/img"

            # 拼接需要向数据库存储的图书图片路径信息
            bookimg = os.path.join(bookimg_path, bookimg_name)

            # 将图片真正的存储至服务器指定位置
            with open(bookimg, "wb") as file:
                # 将文件一点点读取并写入
                for chunk in bookimg_obj.chunks():
                    file.write(chunk)

            bookimg = "/" + bookimg
        else:
            #说明用户没有提交新的修改的图片  接收隐藏域中的默认图片路径
            bookimg = request.POST.get("bookimgname")

        # 通过 持久化对象 设置要修改的属性
        update_book.bookname = bookname
        update_book.bookauthor = bookauthor
        update_book.bookprice = bookprice
        update_book.press_id = press_id
        update_book.bookimg = bookimg

        # 通过 orm 调用save方法，将持久化对象重新保存（更新）
        update_book.save()   # update ....

        # 跳转页面 出版社列表
        return redirect("/booklist")


    # 接收前台页面要删除的id编号
    update_id = request.GET.get("id")
    # 调用orm 查询id对应的出版社对象信息   select * from app_press where id = ?
    book = Book.objects.get(id=update_id)

    # 将所有的出版社列表信息查询并发送至前台修改页面
    presslist = Press.objects.all()

    # 跳转页面 出版社列表
    return render(request,"bookupdate.html",{"book":book,"presslist":presslist})

# 出版社搜索  presssearch
@login_decorator
def booksearch(request):

    bookname = request.POST.get("bookname")

    booklist = Book.objects.filter(bookname__icontains=bookname)
    # 跳转至出版社列表页面
    return render(request,"booklist.html",{"booklist":booklist,"bookname":bookname})

# 图书类型列表
def booktypelist(request):
    # 调用orm查询所有类型信息  select * from app_booktype
    booktypelist = Booktype.objects.all()

    # 跳转至出版社列表页面
    return render(request,"booktypelist.html",{"booktypelist":booktypelist})

# 图书类型列表
def booktypeadd(request):

    if request.method == "POST":
        typename = request.POST.get("typename")
        bookids = request.POST.getlist("bookids")

        # 调用orm执行添加操作 添加类型表与中间表
        booktype = Booktype.objects.create(typename=typename)

        # 配置多对多关联关系
        booktype.books.set(bookids)

        # 重定向列表页面
        return redirect("/booktypelist")

    # 查询所有图书
    booklist = Book.objects.all()
    # 跳转至出版社列表页面
    return render(request,"booktypeadd.html",{"booklist":booklist})

# 图书类型删除  delete
def booktypedelete(request):
    # 接收前台页面要删除的id编号
    delete_id = request.GET.get("id")
    # 调用orm删除 根据id 出版社信息
    Booktype.objects.filter(id=delete_id).delete()
    # 跳转页面 出版社列表
    return redirect("/booktypelist")
    #

# 图书类型更新  delete
def booktypeupdate(request):

    if request.method == "POST":
        # 从修改页面接收所有数据，包含隐藏域中的id值
        id = request.POST.get("id")
        typename = request.POST.get("typename")
        bookids = request.POST.getlist("bookids")

        # 调用 orm 执行修改方法  持久化对象
        update_booktype = Booktype.objects.get(id=id)

        # 通过 持久化对象 设置要修改的属性
        update_booktype.typename = typename
        # 通过 orm 调用save方法，将持久化对象重新保存（更新）
        update_booktype.save()   # update ....

        update_booktype.books.set(bookids)

        # 跳转页面 出版社列表
        return redirect("/booktypelist")


    # 接收前台页面要删除的id编号
    update_id = request.GET.get("id")
    # 调用orm 查询id对应的出版社对象信息   select * from app_press where id = ?
    booktype = Booktype.objects.get(id=update_id)

    # 将所有的出版社列表信息查询并发送至前台修改页面
    booklist = Book.objects.all()

    # 跳转页面 出版社列表
    return render(request,"booktypeupdate.html",{"booktype":booktype,"booklist":booklist})

def getBookByName(request):
    #接收页面ajax发送的数据
    bookname = request.POST.get("bookname")

    # 调用 orm 向数据库查询图书名称是否存在
    if Book.objects.filter(bookname=bookname):
        return HttpResponse("ERROR")
    return HttpResponse("OK")

from django.core.handlers.wsgi import WSGIRequest


def requestTest(request):
    print(request,type(request))
    # 获得请求方法  GET  POST  PUT  DELETE
    """
    get:
        01. 直接刷新地址栏
        02. a连接 href
        03. window.location.href
        04. form表单中 method="get"
        05. ajax中设置get请求方式  type:"get"
    post:
        01. form表单中 method="post"
        02. ajax中设置post请求方式  type:"post"
    """
    #print(request.method)

    # 获得get请求中的参数（从字典中获取key）
    #print(request.GET.get("id"))
    # 获得post请求中的参数（从字典中获取key）
    #print(request.POST.get("id))

    #获得上传的文件
    #print(request.FILES)

    # 获得请求路径
    #print(request.path)
    #print(request.path_info)
    #获取请求体
    #print(request.body)
    # 获取请求协议
    #print(request.scheme)
    #print(request.encoding)
    #print(request.META)
    # 127.0.0.1:8000
    print(request.get_host())
    # 8000
    print(request.get_port())

    print(request.get_full_path())
    print(request.get_full_path_info())

    print(request.is_ajax())

    return HttpResponse("OK")


"""
response响应数据
    01. 转发或重定向，带数据响应
    02. 直接响应字符串
    03. 响应字典（json数据）
        手动拼接json格式
        json.dumps(字典)   test/html    MIME格式
        JsonResponse(字典)   applicaiont/json

"""

import json
from django.http import JsonResponse
def responseTest(request):

    #name = "OK"

    #name = "{\"username\":\"zhangsan\",\"age\":25}"

    name = {"username":"lufei","age":20}

    #re = json.dumps(name)

    #print(re)
    #
    #return HttpResponse(json.dumps(name))
    return JsonResponse(name)

def urltest(request,year):
    print("路由测试")
    print(year,type(year))
    return  HttpResponse("OK")